package com.liked.service.impl;

import com.alibaba.fastjson.JSON;
import com.api.client.IdClient;
import com.api.client.VideoClient;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.constant.RedisKey;
import com.common.context.UserContext;
import com.common.domain.po.LikedRecord;
import com.common.exception.CodeAndMsg;
import com.common.exception.JavaSmException;
import com.liked.mapper.LikedRecordMapper;
import com.liked.service.LikedRecordService;
import lombok.RequiredArgsConstructor;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime;

/**
 * @author 路亚
 * @version 0.1
 * @className LikedRecordServiceImpl
 * @description
 * @date 2024/12/30 21:32
 * @since jdk11
 */
@Service
@RequiredArgsConstructor
public class LikedRecordServiceImpl extends ServiceImpl<LikedRecordMapper, LikedRecord> implements LikedRecordService {

    private final StringRedisTemplate stringRedisTemplate;

    private final VideoClient videoClient;

    private final IdClient idClient;

    private final DefaultMQProducer defaultMQProducer;

    private final LikedRecordMapper likedRecordMapper;

    private static String LIKED_RECORD_TYPE = "liked_record";

    @Override
    public void add(Long videoItemId) {
        // 1.判断是否点过赞
        // 从redis里获取用户点赞记录，使用用户id作为key，点赞记录作为value的hash类型做判断
        // 如果用户对应的记录为空或者0，则表示用户没有点过赞
        // 如果用户对应的记录值为1，则表示用户已经点过赞
        // 如果用户对应的记录值是2，则表示用户已经点过赞，并且保存过了
        String isLikedKey = RedisKey.LIKED_IS_LIKED_KEY + videoItemId;
        Long userId = UserContext.getCurrentId();
        String value = (String) stringRedisTemplate.opsForHash().get(isLikedKey, userId + "");
        if ("1".equals(value)){
            stringRedisTemplate.opsForHash().put(isLikedKey, userId + "", "0");
            try {
                Message message = new Message(
                        "videoLikedRecord",
                        "sub",
                        videoItemId.toString().getBytes("utf-8")
                );
                message.putUserProperty("myLabel", "sub");
                defaultMQProducer.send(message);
            }catch (Exception e){
                throw new JavaSmException(CodeAndMsg.MQ_SEND_ERROR);
            }
            return;
        }
        if ("2".equals(value)){
            stringRedisTemplate.opsForHash().put(isLikedKey, userId + "", "0");
            QueryWrapper<LikedRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("video_item_id", videoItemId);
            queryWrapper.eq("user_id", userId);
            queryWrapper.le("create_time", LocalDateTime.now());
            likedRecordMapper.delete(queryWrapper);
            try {
                Message message = new Message(
                        "videoLikedRecord",
                        "sub",
                        videoItemId.toString().getBytes("utf-8")
                );
                message.putUserProperty("myLabel", "sub");
                defaultMQProducer.send(message);
            }catch (Exception e){
                throw new JavaSmException(CodeAndMsg.MQ_SEND_ERROR);
            }
            return;
        }
        // 给点赞过的用户，值设置为1，表示点过赞
        stringRedisTemplate.opsForHash().put(isLikedKey, userId + "", "1");
        LikedRecord likedRecord = videoClient.queryByVideoItemId(videoItemId);
        likedRecord.setId(idClient.getLongKeyInterval(LIKED_RECORD_TYPE));
        likedRecord.setUserId(userId);
        // 2.保存数据
        // 保存数据还需要给短剧行的点赞数量加1
        // 这里采用Rocketmq 消息队列来完成，效率比远程调用高很多
        // 先把数据存在redis中，再写一个定时任务，定时处理
        String addKey = RedisKey.LIKED_ADD_KEY;
        stringRedisTemplate.opsForList().rightPush(addKey, JSON.toJSONString(likedRecord));
        try {
            Message message = new Message(
                    "videoLikedRecord",
                    "add",
                    videoItemId.toString().getBytes("utf-8")
            );
            message.putUserProperty("myLabel", "add");
            defaultMQProducer.send(message);
        } catch (Exception e) {
            throw new JavaSmException(CodeAndMsg.MQ_SEND_ERROR);
        }
    }
}
